package com.base.cn.platform.os.controller.upload;

import com.base.cn.platform.os.common.StaticBaseController;
import com.base.cn.platform.os.common.md5.MD5;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.file.FileUtil;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * 通过文件上传Controller
 *
 * @author s.li
 * @create 2018-04-05-19:37
 */
@RestController
@Slf4j
public class UploadCommonController extends StaticBaseController {
    @Autowired
    private Environment environment;

    private static String rootDir = "";
    private static String staticPath = "";

    @PostConstruct
    public void init(){
        rootDir = environment.getProperty("root.dir");
        staticPath = environment.getProperty("static.path");
        String osName = environment.getProperty("os.name");
        if(osName.contains("Mac") || osName.contains("Window")){
            rootDir = ClassUtils.getDefaultClassLoader().getResource("").getPath() + rootDir;
        }
    }
    /**
     *  生成剪切图片
     * @param request HttpServletRequest
     * @param file 上传文件的对象
     * @param fileParams 附带的参数
     * @return Map<String,Object>
     */
    @PostMapping(value = "/uploadFile",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map<String,Object> uploadFile(HttpServletRequest request,
                                         @RequestPart(value = "file") MultipartFile file,
                                         @RequestParam(value = "fileParams",required = false) String fileParams) throws Exception{
        if(StringUtils.isNotEmpty(fileParams)){//要剪切
            fileParams = URLDecoder.decode(fileParams,"utf-8");
            Map<String,Object> cutData = gson.fromJson(fileParams,new TypeToken<Map<String,Object>>(){}.getType());
            Map<String,Object> urlMap = FileUtil.saveFile(request,rootDir,staticPath,file,cutData);
            return ResultUtil.SUCCESS("文件上传成功",urlMap);
        }else{//普通上传
            Map<String,String> urlMap = FileUtil.saveFile(request,rootDir,staticPath,file);
            return ResultUtil.SUCCESS("文件上传成功",urlMap);
        }
    }

    /**
     * 上传数据流的图片
     * @param imageDataList 数据流列表，每个元素代表一张图片
     * @param params 目录名
     * @return Map<String,Object>
     */
    @RequestMapping("/updateByteFileData")
    public Map<String,Object> updateByteFileData(HttpServletRequest request,
                                                 @RequestBody List<Map<String, byte[]>> imageDataList,
                                                  @RequestParam(value = "params",required = false,defaultValue = "") String params) throws IOException {
        if(ObjectUtils.isNotEmpty(imageDataList)){
            String tenantId = request.getParameter("tenantId");
            String path = "/upload";
            if(StringUtils.isEmpty(tenantId)){
                tenantId = "/0";
            }
            path += "/"+tenantId;
            if(StringUtils.isEmpty(params)){
                path += "/common";
            }else{
                path +="/"+params;
            }
            path += "/"+ DateUtils.format(new Date(),"yyyyMMddHH");
            Map<Integer,String> imgUrlMap = new HashMap<>();
            int start = 1;
            for(Map<String, byte[]> fileMap : imageDataList){
                List<String> keyList = new ArrayList<>(fileMap.keySet());
                for(String key : keyList){
                    String fileName = MD5.getMD5(System.currentTimeMillis()+StringUtils.getRandomString(32)) +"."+key;
                    File file = new File(rootDir + path);
                    if(!file.exists()){
                        file.mkdirs();
                    }
                    OutputStream os =null;
                    String _path = path + "/" + fileName;
                    String fileUrl = rootDir + _path;
                    try{
                        os = new FileOutputStream(fileUrl);
                        os.write(fileMap.get(key));
                        os.flush();
                        os.close();
                        imgUrlMap.put(start, staticPath + "/" +_path);
                    }catch (Exception e){
                        os.close();
                        return ResultUtil.ERROR("上传文件失败");
                    }
                }
                start +=1;
            }
            return ResultUtil.SUCCESS(imgUrlMap);
        }
        return ResultUtil.ERROR("没有文件内容，上传失败");
    }

    /**
     * 上传压缩报用于广告页
     * @param file 上传文件的对象
     * @param fileParams 附带的参数
     * @return Map<String,Object>
     */
    @RequestMapping("/advertUploadFile")
    public Map<String,Object> advertUploadFile(
            @RequestPart(value = "file") MultipartFile file,
            @RequestParam(value = "fileParams",required = false) String fileParams) throws IOException {
        try{
            String fileName = file.getOriginalFilename();
            fileName = fileName.substring(0,fileName.lastIndexOf("."));
            Pattern pat = Pattern.compile("^[a-zA-Z0-9_\\-]+$");
            Matcher mat = pat.matcher(fileName);
            if(!mat.matches()){
                return ResultUtil.ERROR("文件名只能是英文、数字、下划线");
            }
            StringBuilder savePath  = new StringBuilder().append(rootDir).append("/banner").append("/").append(fileName);
            if(new File(savePath.toString()).exists()){
                return ResultUtil.ERROR("该文件名已存在",null);
            }
            String originalFilename = file.getOriginalFilename();
            savePath = savePath.append("/").append(originalFilename);
            File saveSrcFile = new File(savePath.toString());
            if(!saveSrcFile.getParentFile().exists()){
                saveSrcFile.getParentFile().mkdirs();
            }
            file.transferTo(saveSrcFile);
            //FileUtils.
            //解压目录
            String unZipDir = savePath.toString().replace(file.getOriginalFilename(),"");
            File _zipFile = new File(savePath.toString());
            ZipFile zipFile = new ZipFile(_zipFile, Charset.forName("GBK"));
            Enumeration<ZipEntry> e = (Enumeration<ZipEntry>) zipFile.entries();
            while (e.hasMoreElements()){
                ZipEntry zipEntry = e.nextElement();
                logger.info("--------------- zipEntry file name :"+zipEntry.getName());
                if(zipEntry.isDirectory()) {
                    String name = zipEntry.getName();
                    name = name.substring(0,name.length()-1);
                    File f = new File(unZipDir +"/"+ name);
                    f.mkdirs();
                } else {
                    File f = new File(unZipDir+ "/" + zipEntry.getName());
                    f.getParentFile().mkdirs();
                    f.createNewFile();
                    InputStream is = zipFile.getInputStream(zipEntry);
                    FileOutputStream fos = new FileOutputStream(f);
                    int length = 0;
                    byte[] b = new byte[1024];
                    while((length=is.read(b, 0, 1024))!=-1) {
                        fos.write(b, 0, length);
                    }
                    fos.close();
                    is.close();
                }
            }
            zipFile.close();
            saveSrcFile.delete();
            String url =  savePath.toString().replace(originalFilename,"index.html").replace(rootDir,staticPath+"/");
            Map<String,String> fileData = new HashMap<>();
            fileData.put("url",url);
            return ResultUtil.SUCCESS(fileData);
        }catch (Exception e){
            logger.error("updateAdvertZip()--error",e);
            return ResultUtil.ERROR("系统错误，广告专题上传失败");
        }
    }

}
